package com.scalar.chiptrack.operations.process.actions;

import com.scalar.chiptrack.ChipTrackAction;
import com.scalar.chiptrack.commons.Constants;
import com.scalar.chiptrack.commons.SessionKeys;
import com.scalar.chiptrack.db.DBTransaction;
import com.scalar.chiptrack.operations.process.forms.BomPartEntryForm;
import com.scalar.chiptrack.operations.process.dao.KitMakingDAO;
import com.scalar.chiptrack.operations.process.dao.ProductDao;
import com.scalar.chiptrack.operations.process.dao.VendorLocationDAO;
import com.scalar.chiptrack.operations.process.dao.BomPartEntryDAO;
import com.scalar.chiptrack.operations.process.ProcessStep;
import com.scalar.chiptrack.operations.process.VendorLocation;
import com.scalar.chiptrack.operations.vendor.dao.VendorDAO;
import com.scalar.ScalarException;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.action.ActionForm;
import org.apache.struts.util.LabelValueBean;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.util.HashMap;
import java.util.ArrayList;

/**
 * User: Murali Krishna Yengala
 * Date: May 12, 2005
 * Time: 10:45:13 AM
 */

public class BomPartEntryAction extends ChipTrackAction
{

    public ActionForward execute( ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response ) throws Exception
    {
        BomPartEntryForm bomPartEntryForm   = ( BomPartEntryForm ) form;
        HashMap<String, String> info        = new HashMap<String, String>();
        HashMap<String, String> errors      = new HashMap<String, String>();
        HttpSession mSession                = request.getSession();
        String action                       = request.getParameter( "action" );
        
        action = action == null ? "" : action.trim();


        if ( action.equalsIgnoreCase( "selectBom" ) )
        {
            bomPartEntryForm.setProductId ( -1 );
        }
        else if( action.equalsIgnoreCase( "LoadLocations" ) )
        {
            if( Constants.LOCATION_TYPE_DIE_BANK.equalsIgnoreCase(bomPartEntryForm.getProcessType() ) )
            {
                bomPartEntryForm.setVendorLocations ( VendorDAO.getDieBankLocations() );
            }
            else if( Constants.LOCATION_TYPE_ASSEMBLY.equalsIgnoreCase(bomPartEntryForm.getProcessType() ) )
            {
                bomPartEntryForm.setVendorLocations ( VendorDAO.getAssemblyLocations() );
            }
            else if( Constants.LOCATION_TYPE_FINISHED_GOODS.equalsIgnoreCase( bomPartEntryForm.getProcessType() ) )
            {
                bomPartEntryForm.setVendorLocations ( VendorDAO.getFinishedGoodsLocations() );
            }
            request.setAttribute ( "showDetails" , "TRUE" );
        }
        else if ( action.equalsIgnoreCase( "OpenBom" ) )
        {
            String productId = "" + bomPartEntryForm.getProductId();

            if ( productId.equals ( "-2" ) )
            {
                bomPartEntryForm = new BomPartEntryForm();
                bomPartEntryForm.setProcessType( Constants.LOCATION_TYPE_DIE_BANK ); //default
                bomPartEntryForm.setProductId ( -2 );
                bomPartEntryForm.setProductType( "BOM" );
                bomPartEntryForm.setVendorLocations ( VendorDAO.getDieBankLocations() );
            }
            else
            {
                 //bomPartEntryForm = BomPartEntryDAO.loadBomDetails ( productId.trim ());
                //Modified to avoid the Conn Close Exception by passing the dbTransaction for getting the conn object
                DBTransaction dbTransaction = null;
                try
                {
                    dbTransaction = DBTransaction.getInstance ();
                    bomPartEntryForm = BomPartEntryDAO.loadBomDetails ( productId.trim (), dbTransaction );
                }
                catch( Exception e ){
                    e.printStackTrace();
                }
            }

            mSession.setAttribute ( "bomPartEntryForm" , bomPartEntryForm );
            request.setAttribute ( "showDetails" , "TRUE" );
        }
        else if ( ( action.equals ( "SaveBomPart" ) ) )
        {
            DBTransaction dbTransaction = null;
            boolean success 	= false;
            int processStepId 	= -1;
            int productId 		= -1;
			String STEP_TYPE 	= bomPartEntryForm.getProcessType();

            String productType 	= bomPartEntryForm.getProductType();

            String partNumber 	= bomPartEntryForm.getPartNbr().trim();

			String description 	= "";
            ArrayList<VendorLocation> locations = getVendorLocations( request );

			bomPartEntryForm.setVendorLocations ( locations );
			if ( bomPartEntryForm.getProcessStepId() != -1 )
			{
				processStepId = bomPartEntryForm.getProcessStepId ();
			}
			if ( bomPartEntryForm.getProductId () != -1 )
			{
				productId = bomPartEntryForm.getProductId ();
			}
			if ( bomPartEntryForm.getDescription () != null )
			{
				description = bomPartEntryForm.getDescription();
			}

			ArrayList<VendorLocation> selectedVendorLocations = getVendorLocations( request, true );

            try
            {
                // start transaction
                dbTransaction = DBTransaction.getInstance ();
                dbTransaction.begin ();


                if ( processStepId == -1 )
                {
                    String tempproductId = ProductDao.getProductId ( dbTransaction , partNumber , true );

                    if ( tempproductId != null && !"".equalsIgnoreCase ( tempproductId.trim() ) )
                    {
                        errors.put ( "Same Part Number " + partNumber + " already Present" , " Please Enter Another PartNumber" );
                        throw new ScalarException ( "Same Part Number already Present" );
                    }

                    // Check for partnumber in Product map table
                    String[] partNumbers = new String[ 1 ];
                    partNumbers[ 0 ] = partNumber;

                    String dupNames = ProductDao.checkDupInProductMapTable ( partNumbers , processStepId , STEP_TYPE );
                    if( dupNames != null && dupNames.length () > 0 )
                    {
                        errors.put ( "Same Part Number " + partNumber + " already Present" , " Please Enter Another PartNumber" );
                        throw new ScalarException ( "Same Part Number already Present" );
                    }

                    processStepId = ProcessStep.getProcessStepID ( dbTransaction , STEP_TYPE , STEP_TYPE , description );

                    // Store Product Table information
                    productId = ProductDao.saveProcessStepProduct ( dbTransaction ,
                            processStepId ,
                            partNumber ,
                            -1 ,
                            partNumber ,
                            description ,
                            "1" ,
                            productType
                    );

                    String[] paramKeys = {"Min Qty", "Max Qty", "Reorder Level"};
                    String[] paramUnits = {"UNITS","UNITS","UNITS"};
                    String[] paramValues = {bomPartEntryForm.getMinQuantity(), bomPartEntryForm.getMaxQuantity(), bomPartEntryForm.getReorderLevel()};
                    BomPartEntryDAO.saveParameters( dbTransaction, ""+processStepId, paramKeys, paramUnits, paramValues);

                    //BomPartEntryDAO.saveVendorPartNbr( dbTransaction, processStepId, bomPartEntryForm.getVendorPartNbr(), true);
                    BomPartEntryDAO.saveAlternateVendorPartNbrs( dbTransaction, processStepId, bomPartEntryForm.getAlternateVendorParts() );

                    // Save part number in Inventory Step Table
                    BomPartEntryDAO.saveBomInInventory( dbTransaction , partNumber , processStepId , true ); //true is for insert

                    // Save vendor locations
                    if ( ( locations != null ) && ( locations.size () > 0 ) )
                    {
                        VendorLocationDAO.saveVendorLocations ( dbTransaction , processStepId , selectedVendorLocations.iterator () );
                    }
                }
                else
                {
                    // to check whether another PartNumber is available with same partNumber
                    mSession.setAttribute( "kitActionType" , "modify" );
                    String tempproductId = ProductDao.getProductId ( dbTransaction , partNumber , true );
                    if ( tempproductId == null ) tempproductId = "";
                    tempproductId = tempproductId.trim ();
                    if ( (tempproductId != "") && ( !tempproductId.equalsIgnoreCase ( productId + "" ) ) )
                    {
                        errors.put ( "Same Part Number " + partNumber + " already Present" , " Please Enter Another PartNumber" );

                        throw new ScalarException ( "Same Part Number already Present" );
                    }

                    // To check in Product map table
                    String[] partNumbers = new String[ 1 ];
                    partNumbers[ 0 ] = partNumber;
                    String dupNames = ProductDao.checkDupInProductMapTable ( partNumbers , processStepId , STEP_TYPE );
                    String originalPartNumber = request.getParameter ( "originalPartNumber" );
                    if ( dupNames == null )
                        dupNames = "";
                    if ( ( dupNames != "" ) && ( !dupNames.equalsIgnoreCase ( originalPartNumber ) ) )
                    {
                        errors.put ( "Same Part Number " + partNumber + " already Present" , " Please Enter Another PartNumber" );

                        throw new ScalarException ( "Same Part Number already Present" );

                    }

                    //Update Process Step Table
                    ProcessStep.updateProcessStepID ( dbTransaction , STEP_TYPE , STEP_TYPE , description , processStepId );

                    // update product type and Description
                    KitMakingDAO.updateProductTypeAndDescription ( dbTransaction , productId , productType , description , partNumber , partNumber , 1 );


                    String[] paramKeys = {"Min Qty", "Max Qty", "Reorder Level"};
                    String[] paramUnits = {"UNITS","UNITS","UNITS"};
                    String[] paramValues = {bomPartEntryForm.getMinQuantity(), bomPartEntryForm.getMaxQuantity(), bomPartEntryForm.getReorderLevel()};
                    BomPartEntryDAO.saveParameters( dbTransaction, ""+processStepId, paramKeys, paramUnits, paramValues);

                    //BomPartEntryDAO.saveVendorPartNbr( dbTransaction, processStepId, bomPartEntryForm.getVendorPartNbr(), false);
                    BomPartEntryDAO.saveAlternateVendorPartNbrs( dbTransaction, processStepId, bomPartEntryForm.getAlternateVendorParts() );
                    
                    // Save part number in Inventory Step Table
                    BomPartEntryDAO.saveBomInInventory( dbTransaction , partNumber , processStepId , false ); //false for update

                    // Delete and Save new Vendor Locations
                    VendorLocationDAO.getLocationsOfRunningLots ( dbTransaction , processStepId , selectedVendorLocations , errors );

                    VendorLocationDAO.deleteVendorLocations ( dbTransaction , processStepId );
                    if ( ( locations != null ) && ( locations.size () > 0 ) )
                    {
                        VendorLocationDAO.saveVendorLocations ( dbTransaction , processStepId , selectedVendorLocations.iterator () );
                    }
                }
                success = true;
            }
            catch ( ScalarException se )
            {
                success = false;
                errors.put( se.getMessage(), null );
                request.setAttribute ( SessionKeys.ERROR_MESSAGES , errors );
            }
            catch ( Exception se )
            {
                errors.put ( productType + " Details" , "Problem in saving details" );
                se.printStackTrace ();
                request.setAttribute ( SessionKeys.ERROR_MESSAGES , errors );
            }
            finally
            {
                // Rollback or Commit the Transaction
                if ( success == true )
                {
                    if ( dbTransaction != null )
                    {
                        dbTransaction.commit ();
                    }
                    info.put ( "Bom Details" , partNumber + " saved successfully" );
                }
                else
                {
                    dbTransaction.rollback ();
                }
            }

            if ( success )
            {
                bomPartEntryForm.setProductId ( -1 );
                //formReset( kitMakingForm );
                request.setAttribute ( "showDetails" , "FALSE" );
            }
            else
            {
                bomPartEntryForm.setProductType ( productType );
                bomPartEntryForm.setDescription ( description );

                bomPartEntryForm.setVendorLocations ( locations );
                if ( productId == -2 )
                {
                    bomPartEntryForm.setProductId ( -2 );
                    bomPartEntryForm.setPartNbr ( partNumber );
                }
                else
                {
                    bomPartEntryForm.setProductId ( productId );
                    bomPartEntryForm.setPartNbr ( partNumber );
                }
                request.setAttribute ( "showDetails" , "TRUE" );
            }
            //request.setAttribute ( "bomPartEntryForm" , bomPartEntryForm );
            request.setAttribute ( SessionKeys.INFO_MESSAGES , info );
        }
        request.setAttribute("bomParts", BomPartEntryDAO.loadBomParts());
        request.setAttribute("processTypes", getProcessTypes());
        return mapping.findForward("bomPartEntry");
    }

    private ArrayList<VendorLocation> getVendorLocations ( HttpServletRequest request )
    {
        ArrayList<VendorLocation> vendorLocations = new ArrayList<VendorLocation>();
        String[] locationName = request.getParameterValues ( "locationName" );
        if ( locationName.length == 0 )
        {
            return null;
        }
        String[] priority 	= request.getParameterValues ( "priority" );
        String[] locationID = request.getParameterValues ( "locationID" );
		String select[] = request.getParameterValues ( "select" );
        VendorLocation location = null;
        int selectCount = 0;

        for ( int i = 0 ; i < locationName.length ; i++ )
        {
            try
            {
                if ( priority[ i ].trim ().length () > 0 )
                {    // check if this row was enabled by the user or not
                    // save only if its enabled
                    location = new VendorLocation ( select[ selectCount ] , priority[ i ] ,
                            locationName[ i ] , locationID[ i ] );
                    vendorLocations.add ( location );
                    selectCount++;
                }
                else
                {
                    location = new VendorLocation ( "" , "" , locationName[ i ] , locationID[ i ] );
                    vendorLocations.add ( location );
                }
            }
            catch ( Exception ignore )
            {
            }
        }
        return vendorLocations;
    }

    private ArrayList<VendorLocation> getVendorLocations ( HttpServletRequest request , boolean bool )
    {
        ArrayList<VendorLocation> vendorLocations = new ArrayList<VendorLocation>();
        String[] locationName = request.getParameterValues ( "locationName" );

        if ( locationName.length == 0 )
        {
            return null;
        }
        String[] priority = request.getParameterValues ( "priority" );
        String[] locationID = request.getParameterValues ( "locationID" );
        VendorLocation location = null;
        String select[] = request.getParameterValues ( "select" );
        int selectCount = 0;
        for ( int i = 0 ; i < locationName.length ; i++ )
        {

            try
            {
                if ( priority[ i ].trim ().length () > 0 )
                {    // check if this row was enabled by the user or not
                    // save only if its enabled
                    location = new VendorLocation ( select[ selectCount ] , priority[ i ] ,
                            locationName[ i ] , locationID[ i ] );
                    vendorLocations.add ( location );
                    selectCount++;
                }
            }
            catch ( Exception ignore )
            {
            }
        }
        return vendorLocations;
    }

    private ArrayList getProcessTypes()
    {
        ArrayList<LabelValueBean> processTypes = new ArrayList<LabelValueBean>();
        processTypes.add(new LabelValueBean(Constants.LOCATION_TYPE_DIE_BANK, Constants.LOCATION_TYPE_DIE_BANK));
        //processTypes.add(new LabelValueBean(Constants.LOCATION_TYPE_ASSEMBLY, Constants.LOCATION_TYPE_ASSEMBLY));
        processTypes.add(new LabelValueBean(Constants.LOCATION_TYPE_FINISHED_GOODS, Constants.LOCATION_TYPE_FINISHED_GOODS));
        return processTypes;
    }

}
